package midi.theory;

import midi.basic.Configure;
import midi.basic.Mode;
import midi.basic.Pitch;
import midi.basic.Scale;

public class PitchUtil {
    private static char[] notes = {'C', 'D', 'E', 'F', 'G', 'A', 'B'};

    public static Pitch fromString(String str) {
        //str=##bbC--
        Pitch pitch = new Pitch();
        int position = 0;
        int offset = 0;
        for (int i = 0; i <= str.length() - 1; i++) {
            char c = str.charAt(i);
            if (c == '#') {
                offset++;
            } else if (c == 'b') {
                offset--;
            } else if (c == '+') {
                position++;
            } else if (c == '-') {
                position--;
            } else if (isNote(c)) {
                pitch.setScale(Scale.fromScaleString(String.valueOf(c)));
            }
        }
        pitch.setPosition(position);
        pitch.setOffset(offset);
        return pitch;
    }

    public static String toString(Pitch pitch) {
        String str = "";
        for (int i = 0; i <= Math.abs(pitch.getOffset()) - 1; i++) {
            if (pitch.getOffset() > 0) {
                str += "#";
            } else {
                str += "b";
            }
        }
        str += pitch.getScale().scaleString();
        for (int i = 0; i <= Math.abs(pitch.getPosition()) - 1; i++) {
            if (pitch.getPosition() > 0) {
                str += "+";
            } else {
                str += "-";
            }
        }
        return str;
    }

    //判断是否是音阶符号
    private static boolean isNote(char str) {

        for (int i = 0; i <= notes.length - 1; i++) {
            if (str == notes[i]) {
                return true;
            }
        }
        return false;
    }


    public static int getVoiceId(Pitch pitch) {
        return Configure.MainC + pitch.getScale().offset() + pitch.getOffset() + pitch.getPosition() * 12;
    }

    public static Pitch fromVoiceId(int id) {
        Pitch pitch = new Pitch();
        int position;
        if (id >= 60) {
            position = (id - 60) / 12;
        } else {
            position = ((id - 60 + 1) / 12) - 1;
        }
        int offset = (id - 60) % 12;
        if (offset < 0) {
            offset = 12 - Math.abs(offset);
        }
        Scale scale = null;
        pitch.setPosition(position);
        if (offset == 0) {
            scale = Scale.C;  //1
        } else if (offset == 1) {
            scale = Scale.C;  //#1
            pitch.setOffset(1);
        } else if (offset == 2) {
            scale = Scale.D;        //2
        } else if (offset == 3) {
            scale = Scale.D;        //#2
            pitch.setOffset(1);
        } else if (offset == 4) {
            scale = Scale.E;   //3

        } else if (offset == 5) {
            scale = Scale.F;  //4

        } else if (offset == 6) {
            scale = Scale.F;  //#4
            pitch.setOffset(1);
        } else if (offset == 7) {
            scale = Scale.G;   //5
        } else if (offset == 8) {
            scale = Scale.G;  //#5
            pitch.setOffset(1);
        } else if (offset == 9) {
            scale = Scale.A;  //6

        } else if (offset == 10) {
            scale = Scale.A;
            pitch.setOffset(1);//#6
        } else if (offset == 11) {
            scale = Scale.B;
        }

        pitch.setScale(scale);
        return pitch;
    }

    public static Pitch changeMode(Pitch pitch, Mode mode) {
        return fromVoiceId(getVoiceId(pitch) + mode.getOffset());
    }

    public static Boolean match(Pitch pitch1, Pitch pitch2) {
        return getVoiceId(pitch1) == getVoiceId(pitch2);
    }

}
